/**俄罗斯方块管理类
 * 核心算法：生成地图，生成当前方块，生成下一个方块，左右移动，下落，旋转，
 * 检测是否与其他方块或游戏场地的边缘碰撞，检测游戏是否结束
 * 该管理类只负责数据的管理，不负责UI界面的渲染
 */
window.TetrisManager = {
	data: {
		ROWS: 20,//列数
		COLS: 10,//行数
		CELL_SIZE: 30,//格子大小
		playfield: [],//地图数据
		nextTetr: null,//下一个方块
		isPlay:true,//是否游戏中
		callBack:null,//回调函数
		player: {//角色数据
			pos: { x: 0, y: 0 },
			tetromino: null,
			score: 0
		}
	},
	// 创建游戏场地的二维数组，初始值为0（0代表空格）
	createPlayfield: () => {
		const { playfield, ROWS, COLS } = TetrisManager.data;
		for (let y = 0; y < ROWS; y++) {
			playfield[y] = [];
			for (let x = 0; x < COLS; x++) {
				playfield[y][x] = 0;
			}
		}
		return playfield;
	},
	// 检测方块是否与其他方块或游戏场地的边缘碰撞
	collision: (playfield, playerPos, tetromino) => {
		for (let y = 0; y < tetromino.length; y++) {
			for (let x = 0; x < tetromino[y].length; x++) {
				if (tetromino[y][x] !== 0 && (playfield[y + playerPos.y] && playfield[y + playerPos.y][x + playerPos.x]) !== 0) {
					return true;
				}
			}
		}
		return false;
	},
	// 清除满行
	clearRows: () => {
		const {player, playfield, ROWS, COLS ,callBack} = TetrisManager.data;
		let ys=[];
		for (let y = ROWS - 1; y >= 0; y--) {
			if (playfield[y].every(cell => cell !== 0)) {
				if(callBack)callBack({type:1,y:y});//触发清除满行事件的回调
				player.score += 100; // 假设每清除一行得100分
				ys.push(y);
			}
		}
		//延迟清除，可让UI界面更流畅，还可在UI界面上显示动画效果
		setTimeout(()=>{
			for (let i = 0; i < ys.length; i++) {
				playfield.splice(ys[i]+i, 1);
				playfield.unshift(Array(COLS).fill(0));
			}
		},100)
	},
	moveDown() {
		if (!TetrisManager.isPlaying()) {
			return;
		}
		const { player ,playfield ,callBack} = TetrisManager.data;
		const tetromino = player.tetromino;
		player.pos.y++;
		if (TetrisManager.collision(playfield, player.pos, player.tetromino)) {
			// 如果下落后发生碰撞，将方块固定在场地中，然后生成新的方块
			player.pos.y--;
			TetrisManager.mergePlayerTetromino();
			TetrisManager.createNextTetromino();
			if (tetromino && TetrisManager.isGameOver(tetromino)) {
				console.log('游戏结束了');
				TetrisManager.data.isPlay=false;
				if(callBack)callBack({type:0,tip:'gameOver'});
				//游戏结束了
			}else{
				if(callBack)callBack({type:2,tip:'moveDown'});
			}
			TetrisManager.clearRows(); // 检查并清除满行
		}
	},
	// 向左移动方块
	moveLeft: () => {
		const { player, playfield } = TetrisManager.data;
		player.pos.x--;
		if (TetrisManager.collision(playfield, player.pos, player.tetromino)) {
			// 如果向左移动后发生碰撞，恢复到移动前的位置
			player.pos.x++;
		}
	},
	// 向右移动方块
	moveRight: () => {
		const { player, playfield } = TetrisManager.data;
		player.pos.x++;
		if (TetrisManager.collision(playfield, player.pos, player.tetromino)) {
			// 如果向右移动后发生碰撞，恢复到移动前的位置
			player.pos.x--;
		}
	},
	// 旋转玩家方块
	rotatePlayerTetromino: () => {
		const { player, playfield } = TetrisManager.data;
		const clonedTetromino = JSON.parse(JSON.stringify(player.tetromino));
		const rotatedTetromino = TetrisManager.rotate(clonedTetromino);
		if (!TetrisManager.collision(playfield, player.pos, rotatedTetromino)) {
			player.tetromino = rotatedTetromino;
		}
	},
	// 随机生成新的方块
	createTetromino: () => {
		const tetrominos = 'IJLOSTZ';
		const randTetromino =TetrisManager.TETROMINOS[tetrominos[Math.floor(Math.random() * tetrominos.length)]];
		return randTetromino;
	},
	// 将玩家方块合并到场地中
	mergePlayerTetromino: () => {
		const { player, playfield } = TetrisManager.data;
		for (let y = 0; y < player.tetromino.length; y++) {
			for (let x = 0; x < player.tetromino[y].length; x++) {
				if (player.tetromino[y][x] !== 0) {
					playfield[y + player.pos.y][x + player.pos.x] = 1;
				}
			}
		}
		//console.log(playfield)
	},
	// 旋转方块
	rotate: (tetromino) => {
		const N = tetromino.length;
		for (let y = 0; y < N / 2; y++) {
			for (let x = y; x < N - y - 1; x++) {
				const temp = tetromino[y][x];
				tetromino[y][x] = tetromino[N - 1 - x][y];
				tetromino[N - 1 - x][y] = tetromino[N - 1 - y][N - 1 - x];
				tetromino[N - 1 - y][N - 1 - x] = tetromino[x][N - 1 - y];
				tetromino[x][N - 1 - y] = temp;
			}
		}
		return tetromino;
	},
	// 定义各种形状的方块模板
	TETROMINOS: {
		'I': [
			[0, 0, 0, 0],
			[1, 1, 1, 1],
			[0, 0, 0, 0],
			[0, 0, 0, 0]
		],
		'J': [
			[1, 0, 0],
			[1, 1, 1],
			[0, 0, 0]
		],
		'L': [
			[0, 0, 1],
			[1, 1, 1],
			[0, 0, 0]
		],
		'O': [
			[1, 1],
			[1, 1]
		],
		'S': [
			[0, 1, 1],
			[1, 1, 0],
			[0, 0, 0]
		],
		'T': [
			[0, 1, 0],
			[1, 1, 1],
			[0, 0, 0]
		],
		'Z': [
			[1, 1, 0],
			[0, 1, 1],
			[0, 0, 0]
		]
	},
	// 判断游戏是否结束(获取下一个方块nextTetromino)
	isGameOver(nextTetromino) {
		// 检查是否可以在初始位置放置下一个方块
		var { player, playfield, nextTetr , ROWS, COLS } = TetrisManager.data;
		for (let y = 0; y < nextTetromino.length; y++) {
			for (let x = 0; x < nextTetromino[y].length; x++) {
				if (
					nextTetromino[y][x] !== 0 &&
					(playfield[y] && playfield[y][x + Math.floor(COLS / 2)] !== 0)
				) {
					return true; // 游戏结束
				}
			}
		}
		return false; // 游戏未结束
	},
	//判断游戏是否在运行
	isPlaying(){
		return TetrisManager.data.isPlay;
	},
	//创建下一个方块
	createNextTetromino() {
		var { player, playfield, nextTetr , ROWS, COLS } = TetrisManager.data;
		player.pos = { x: COLS / 2 - 1, y: 0 };
		player.tetromino = nextTetr||TetrisManager.createTetromino();
		TetrisManager.data.nextTetr = TetrisManager.createTetromino(); // 初始化时更新预览方块
	},
	//初始化游戏
	initGame() {
		var { player, playfield, nextTetr, ROWS, COLS } = TetrisManager.data;
		playfield = TetrisManager.createPlayfield();
		nextTetr = TetrisManager.createTetromino(); // 初始化时更新预览方块
		player.pos = { x: COLS / 2 - 1, y: 0 };
		player.score = 0;
		player.tetromino = nextTetr;
		TetrisManager.data.isPlay=true;
		TetrisManager.data.nextTetr=TetrisManager.createTetromino();
	},
}